import { Model, DataTypes, Optional } from 'sequelize';
import sequelize from '@/config/database';

// 定义操作日志属性接口
interface OperLogAttributes {
  operId: number;
  title: string;
  businessType: number;
  method?: string;
  requestMethod?: string;
  operatorType?: number;
  operName?: string;
  deptName?: string;
  operUrl?: string;
  operIp?: string;
  operLocation?: string;
  operParam?: string;
  jsonResult?: string;
  status?: number;
  errorMsg?: string;
  operTime?: Date;
  costTime?: number;
  businessTypes?: number[];
}

// 创建时可选字段
interface OperLogCreationAttributes extends Optional<OperLogAttributes, 'operId'> {}

// 操作日志模型
class OperLog extends Model<OperLogAttributes, OperLogCreationAttributes> implements OperLogAttributes {
  public operId!: number;
  public title!: string;
  public businessType!: number;
  public method?: string;
  public requestMethod?: string;
  public operatorType?: number;
  public operName?: string;
  public deptName?: string;
  public operUrl?: string;
  public operIp?: string;
  public operLocation?: string;
  public operParam?: string;
  public jsonResult?: string;
  public status?: number;
  public errorMsg?: string;
  public operTime?: Date;
  public costTime?: number;
  public businessTypes?: number[];

  // 业务类型常量
  public static readonly BUSINESS_TYPE = {
    OTHER: 0,    // 其它
    INSERT: 1,   // 新增
    UPDATE: 2,   // 修改
    DELETE: 3,   // 删除
    GRANT: 4,    // 授权
    EXPORT: 5,   // 导出
    IMPORT: 6,   // 导入
    FORCE: 7,    // 强退
    GENCODE: 8,  // 生成代码
    CLEAN: 9     // 清空数据
  };

  // 操作状态常量
  public static readonly STATUS = {
    NORMAL: 0,   // 正常
    EXCEPTION: 1 // 异常
  };

  // 操作类别常量
  public static readonly OPERATOR_TYPE = {
    OTHER: 0,    // 其它
    MANAGE: 1,   // 后台用户
    MOBILE: 2    // 手机端用户
  };
}

OperLog.init(
  {
    operId: {
      type: DataTypes.BIGINT,
      primaryKey: true,
      autoIncrement: true,
      field: 'oper_id',
      comment: '日志主键'
    },
    title: {
      type: DataTypes.STRING(50),
      allowNull: false,
      defaultValue: '',
      field: 'title',
      comment: '模块标题'
    },
    businessType: {
      type: DataTypes.INTEGER,
      allowNull: false,
      defaultValue: 0,
      field: 'business_type',
      comment: '业务类型（0其它 1新增 2修改 3删除）'
    },
    method: {
      type: DataTypes.STRING(200),
      allowNull: true,
      defaultValue: '',
      field: 'method',
      comment: '方法名称'
    },
    requestMethod: {
      type: DataTypes.STRING(10),
      allowNull: true,
      defaultValue: '',
      field: 'request_method',
      comment: '请求方式'
    },
    operatorType: {
      type: DataTypes.INTEGER,
      allowNull: true,
      defaultValue: 0,
      field: 'operator_type',
      comment: '操作类别（0其它 1后台用户 2手机端用户）'
    },
    operName: {
      type: DataTypes.STRING(50),
      allowNull: true,
      defaultValue: '',
      field: 'oper_name',
      comment: '操作人员'
    },
    deptName: {
      type: DataTypes.STRING(50),
      allowNull: true,
      defaultValue: '',
      field: 'dept_name',
      comment: '部门名称'
    },
    operUrl: {
      type: DataTypes.STRING(255),
      allowNull: true,
      defaultValue: '',
      field: 'oper_url',
      comment: '请求URL'
    },
    operIp: {
      type: DataTypes.STRING(128),
      allowNull: true,
      defaultValue: '',
      field: 'oper_ip',
      comment: '主机地址'
    },
    operLocation: {
      type: DataTypes.STRING(255),
      allowNull: true,
      defaultValue: '',
      field: 'oper_location',
      comment: '操作地点'
    },
    operParam: {
      type: DataTypes.STRING(2000),
      allowNull: true,
      defaultValue: '',
      field: 'oper_param',
      comment: '请求参数'
    },
    jsonResult: {
      type: DataTypes.STRING(2000),
      allowNull: true,
      defaultValue: '',
      field: 'json_result',
      comment: '返回参数'
    },
    status: {
      type: DataTypes.INTEGER,
      allowNull: true,
      defaultValue: 0,
      field: 'status',
      comment: '操作状态（0正常 1异常）'
    },
    errorMsg: {
      type: DataTypes.STRING(2000),
      allowNull: true,
      defaultValue: '',
      field: 'error_msg',
      comment: '错误消息'
    },
    operTime: {
      type: DataTypes.DATE,
      allowNull: true,
      field: 'oper_time',
      comment: '操作时间'
    },
    costTime: {
      type: DataTypes.BIGINT,
      allowNull: true,
      defaultValue: 0,
      field: 'cost_time',
      comment: '消耗时间'
    },
    // Sequelize虚拟字段 - 业务类型数组，不映射到数据库
    businessTypes: {
      type: DataTypes.VIRTUAL,
      get: function() {
        return [];
      },
      set: function(value: number[]) {
        if (value && value.length > 0) {
          this.setDataValue('businessType', value[0]);
        }
      }
    }
  },
  {
    sequelize,
    tableName: 'sys_oper_log',
    timestamps: false,
    indexes: [
      {
        name: 'idx_sys_oper_log_bt',
        fields: ['business_type']
      },
      {
        name: 'idx_sys_oper_log_s',
        fields: ['status']
      },
      {
        name: 'idx_sys_oper_log_ot',
        fields: ['oper_time']
      }
    ]
  }
);

export default OperLog; 